<template>
  <el-form ref="formRef" :model="form" :rules="rules" class="uploadForm">
    <!-- 上传身份证 -->
    <el-form-item label="身份证" prop="idCardList" class="item">
      <el-upload
        ref="idCardListUpload"
        action=""
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleIdCardListRemove"
        :on-change="handleIdCardListChange"
        :file-list="uploadFiles.idCardList"
        :auto-upload="false"
      >
        <Plus class="plus"/>
      </el-upload>
    </el-form-item>

    <!-- 上传获奖证书 -->
    <el-form-item label="获奖证书" prop="awardCertificatesList" class="item">
      <el-upload
        ref="awardCertificatesUploader"
        action=""
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleAwardCertificateListRemove"
        :on-change="handleAwardCertificateListChange"
        :file-list="uploadFiles.awardCertificatesList"
        :auto-upload="false"
      >
        <Plus class="plus"/>
      </el-upload>
    </el-form-item>

    <!-- 上传专利证书 -->
    <el-form-item label="专利证书" prop="patentsList" class="item">
      <el-upload
        ref="patentUploader"
        action=""
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handlePatentListRemove"
        :on-change="handlePatentListChange"
        :file-list="uploadFiles.patentsList"
        :auto-upload="false"
      >
        <Plus class="plus"/>
      </el-upload>
    </el-form-item>

    <!-- 预览对话框 -->
    <el-dialog v-model="dialogVisible" title="预览图片">
      <img
        :src="dialogImageUrl"
        alt="Preview"
        style="width: 100%; max-height: 70vh; object-fit: contain"
      />
    </el-dialog>

    <!-- 提交按钮 -->
    <el-form-item>
      <el-button type="primary" @click="submitForm" :loading="loading">提交文件</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { ref, reactive, onBeforeUnmount, nextTick } from 'vue';
import type { FormInstance, UploadInstance, UploadFile, UploadProps } from 'element-plus';
import { Plus } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { residencyApplication, residencyApplicationList } from '@/api/enterpeise';
import { uploadFile } from '@/api/file';
import { useRouter } from 'vue-router';
import { reqFeedback } from '@/utils/reqFeedback';

const router = useRouter();
const formRef = ref<FormInstance>();

const form = reactive({
  idCardList: [],
  awardCertificatesList: [],
  patentsList: [],
});

const loading = ref(false);

// 预览相关
const dialogImageUrl = ref('');
const dialogVisible = ref(false);

// 上传组件引用
const idCardListUpload = ref<UploadInstance>();
const awardCertificatesUploader = ref<UploadInstance>();
const patentUploader = ref<UploadInstance>();

// 上传文件存储
interface UploadFilesState {
  idCardList: UploadFile[];
  awardCertificatesList: UploadFile[];
  patentsList: UploadFile[];
}

// 创建响应式数据
const uploadFiles = reactive<UploadFilesState>({
  idCardList: [],
  awardCertificatesList: [],
  patentsList: [],
});

// 表单验证规则
const rules = {
  idCardList: [
    {
      required: true,
      validator: (_: any, value: any, callback: any) => {
        if (uploadFiles.idCardList.length === 0) {
          callback(new Error('请上传身份证照片'));
        } else {
          callback();
        }
      },
      trigger: 'change',
    },
  ],
};

// 图片验证函数
const validateImage = (file: UploadFile) => {
  if (!file.raw) {
    ElMessage.error('文件上传失败');
    return false;
  }

  const isImage = file.raw.type.startsWith('image/');
  const isLt2M = file.raw.size / 1024 / 1024 < 2;

  if (!isImage) {
    ElMessage.error('只能上传图片类型的文件');
    return false;
  }
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过 2MB');
    return false;
  }
  return true;
};

// 预览处理函数
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  if (uploadFile.url) {
    dialogImageUrl.value = uploadFile.url;
  } else if (uploadFile.raw) {
    dialogImageUrl.value = URL.createObjectURL(uploadFile.raw);
  }
  dialogVisible.value = true;
};

// 通用的文件移除处理函数
const handleFileRemove = (file: UploadFile, fileList: UploadFile[]) => {
  const index = fileList.findIndex((f) => f.uid === file.uid);
  if (index !== -1) {
    fileList.splice(index, 1);
  }
  if (file.url?.startsWith('blob:')) {
    URL.revokeObjectURL(file.url);
  }
};

// 通用的文件改变处理函数
const handleFileChange = (
  file: UploadFile,
  fileList: UploadFile[],
  type: 'idCardList' | 'awardCertificatesList' | 'patentsList'
) => {
  const isValid = validateImage(file);
  if (!isValid) {
    return;
  }

  // 创建预览URL
  if (file.raw && !file.url) {
    file.url = URL.createObjectURL(file.raw);
  }

  // 直接给uploadFiles对应的列表赋新值
  uploadFiles[type] = fileList.map((f) => ({
    ...f,
    status: 'success',
  }));
};

// 身份证相关处理函数
const handleIdCardListRemove = (file: UploadFile) => {
  const index = uploadFiles.idCardList.findIndex((f) => f.uid === file.uid);
  if (index !== -1) {
    // 创建新数组并赋值，保持响应性
    const newList = [...uploadFiles.idCardList];
    newList.splice(index, 1);
    uploadFiles.idCardList = newList;
  }
  // 释放URL
  if (file.url?.startsWith('blob:')) {
    URL.revokeObjectURL(file.url);
  }
  nextTick(() => {
    formRef.value?.validateField('idCardList');
  });
};

// 身份证相关处理函数
const handleIdCardListChange = (file: UploadFile, fileList: UploadFile[]) => {
  handleFileChange(file, fileList, 'idCardList');
  nextTick(() => {
    formRef.value?.validateField('idCardList');
  });
};

// 获奖证书相关处理函数
const handleAwardCertificateListChange = (file: UploadFile, fileList: UploadFile[]) => {
  handleFileChange(file, fileList, 'awardCertificatesList');
};

const handleAwardCertificateListRemove = (file: UploadFile) => {
  const index = uploadFiles.awardCertificatesList.findIndex((f) => f.uid === file.uid);
  if (index !== -1) {
    const newList = [...uploadFiles.awardCertificatesList];
    newList.splice(index, 1);
    uploadFiles.awardCertificatesList = newList;
  }
  if (file.url?.startsWith('blob:')) {
    URL.revokeObjectURL(file.url);
  }
};

// 专利证书相关处理函数
const handlePatentListChange = (file: UploadFile, fileList: UploadFile[]) => {
  handleFileChange(file, fileList, 'patentsList');
};

const handlePatentListRemove = (file: UploadFile) => {
  const index = uploadFiles.patentsList.findIndex((f) => f.uid === file.uid);
  if (index !== -1) {
    const newList = [...uploadFiles.patentsList];
    newList.splice(index, 1);
    uploadFiles.patentsList = newList;
  }
  if (file.url?.startsWith('blob:')) {
    URL.revokeObjectURL(file.url);
  }
};

// 上传单个文件的工具函数
const uploadSingleFile = async (file: UploadFile): Promise<string> => {
  const formData = new FormData();
  formData.append('file', file.raw as Blob);
  const res: any = await uploadFile(formData);
  if (res.code === 200) {
    return res.data.url;
  }
  throw new Error('文件上传失败');
};

// 提交表单
const submitForm = async () => {
  if (!formRef.value) return;

  try {
    loading.value = true;
    await formRef.value.validate();

    const requestData = {
      idCard: [] as string[],
      certificate: [] as string[],
      patent: [] as string[],
    };

    // 上传所有文件
    try {
      // 上传身份证
      requestData.idCard = await Promise.all(
        uploadFiles.idCardList.map((file) => uploadSingleFile(file))
      );

      // 上传获奖证书
      requestData.certificate = await Promise.all(
        uploadFiles.awardCertificatesList.map((file) => uploadSingleFile(file))
      );

      // 上传专利
      requestData.patent = await Promise.all(
        uploadFiles.patentsList.map((file) => uploadSingleFile(file))
      );

      residencyApplication(requestData).then((res: any) => {
        reqFeedback(res, '提交文件成功');
      });
    } catch (error) {
      ElMessage.error((error as Error).message || '上传失败');
    }
  } catch (error) {
    ElMessage.error('请检查表单填写是否正确');
  } finally {
    loading.value = false;
  }
};

// 组件卸载前清理资源
onBeforeUnmount(() => {
  const allFiles = [
    ...uploadFiles.idCardList,
    ...uploadFiles.awardCertificatesList,
    ...uploadFiles.patentsList,
  ];

  allFiles.forEach((file) => {
    if (file.url?.startsWith('blob:')) {
      URL.revokeObjectURL(file.url);
    }
  });
});
</script>

<style scoped>
.uploadForm {
  display: flex;
  flex-wrap: wrap;

}
.item {
  margin: 20px 30px;
}
.plus {
  width: 30px;height: 30px;
}
.el-upload {
  width: 178px;
  height: 178px;
  line-height: 178px;
}
</style>
